MyBatis基础
什么是 MyBatis
Mybatis 是一个半 ORM 框架,内部封装了 JDBC,开发时只需要关注 sql 语句本身,不用去处理加载驱动,创建连接等过程
程序员可以直接编写原生 sql,可以严格控制 sql 执行性能,灵活度高
MyBatis 可以使用 xml 或注解来配置和映射原生信息,将 pojo 映射成数据库中的记录
ORM 是什么
ORM,对象关系映射,是一种为了解决关系型数据库数据与简单 Java 对象的映射关系的技术
通过使用描述对象和数据库之间映射的元数据,将程序中的对象自动持久化到关系型数据库中
为什么说 Mybatis 是半自动 ORM 映射工具?它与全自动的区别在哪里?
Hibernate 属于全自动 ORM 映射工具,使用 Hibernate 查询关联对象或者关联集合对象时,可以根据对象关系模型直接获取
Mybatis 在查询关联对象或关联集合对象时,需要手动编写 SQL 来完成
MyBatis 使用过程
创建 SqlSessionFactory
SqlSessionFactory 是 MyBatis 框架中的核心接口,它是创建 SqlSession 的工厂类,负责管理数据库会话的创建和配置
- 创建 SqlSession:作为工厂类,生产 SqlSession 实例
- 管理数据库配置:持有 MyBatis 的所有配置信息
- 线程安全:SqlSessionFactory 一旦创建,可以在应用运行期间一直存在
创建 SqlSession
SqlSession(会话)可以理解为程序和数据库之间的桥梁
通过 sqlsession 执行数据库操作
可以通过 SqlSession 实例来直接执行已映射的 SQL 语句:
Blog blog = (Blog)session.selectOne("org.mybatis.example.BlogMapper.selectBlog", 101);更常用的方式是先获取 Mapper(映射),然后再执行 SQL 语句:
BlogMapper mapper = session.getMapper(BlogMapper.class);
Blog blog = mapper.selectBlog(101);如果是更新、删除语句,我们还需要提交一下事务。
最后一定要调用 session.close()关闭会话
#{}和${}的区别?
#{} 是预编译处理,${} 是字符串替换
当使用 #{} 时,MyBatis 会在 SQL 执行之前,将占位符替换为问号 ?,并使用参数值来替代这些问号
当使用 ${} 时,参数的值会直接替换到 SQL 语句中去,而不会经过预处理
Mybatis 的一级、二级缓存
- 一级缓存: 一级缓存作用范围是 SqlSession。它本质上是一个本地缓存,同一个会话中重复查询相同数据时可以减少数据库访问,但跨 SqlSession 不共享
- 二级缓存是 Mapper 维度的,多个 SqlSession 可以共享。但在实际项目里用得不算特别多,因为缓存一致性不好控制,尤其是在分布式场景下,很多时候会更倾向于用 Redis 做统一缓存。
如何防止 sql 注入
使用参数化查询
使用参数化查询,即使用PreparedStatement对象,通过setXxx方法设置参数值,而不是通过字符串拼接 SQL 语句。这样可以有效防止 SQL 注入
String query = "SELECT * FROM users WHERE username = ?";
PreparedStatement pstmt = connection.prepareStatement(query);
pstmt.setString(1, userName); // userName 是用户输入
ResultSet rs = pstmt.executeQuery();限制用户输入
对用户输入进行验证和过滤,只允许输入预期的数据,不允许输入特殊字符或 SQL 关键字
使用 ORM 框架
在 MyBatis 中,使用#{}占位符来代替直接拼接 SQL 语句,MyBatis 会自动进行参数化处理